package com.jieli.stream.dv.running2.ui.fragment;


import android.content.Context;
import android.graphics.Color;
import android.net.wifi.WifiInfo;
import android.net.wifi.p2p.WifiP2pDevice;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.jieli.lib.dv.control.mssdp.Discovery;
import com.jieli.stream.dv.running2.R;
import com.jieli.stream.dv.running2.bean.DeviceBean;
import com.jieli.stream.dv.running2.ui.MainApplication;
import com.jieli.stream.dv.running2.ui.activity.MainActivity;
import com.jieli.stream.dv.running2.ui.base.BaseFragment;
import com.jieli.stream.dv.running2.ui.dialog.SelectWifiDialog;
import com.jieli.stream.dv.running2.util.ClientManager;
import com.jieli.stream.dv.running2.util.Dbug;
import com.jieli.stream.dv.running2.util.IConstant;
import com.jieli.stream.dv.running2.util.ToastUtil;
import com.jieli.stream.dv.running2.util.WifiHelper;
import com.jieli.stream.dv.running2.util.WifiP2pHelper;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class StaDeviceListFragment extends BaseFragment implements View.OnClickListener, AdapterView.OnItemClickListener {
    private static String tag = StaDeviceListFragment.class.getSimpleName();
    private ListView deviceListView;
    private DeviceListAdapter mAdapter;
    private SwipeRefreshLayout mSwipeRefreshLayout;
    private SearchStaDevice mSearchStaDevice;
    private boolean isRefreshing = false;//是否刷新中
    private TextView tvPullToRefresh;

    private SelectWifiDialog mSelectWifiDialog;
    private List<String> mStationList = new ArrayList<>();

    private final static int MSG_SEARCH_DEVICE_LIST = 0x457;
    private final static int MSG_ADD_NEW_DEVICE = 0x458;
    private final Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            if (message != null && !isDetached()) {
                switch (message.what) {
                    case MSG_SEARCH_DEVICE_LIST: {
                        refreshList();
                        break;
                    }
                    case MSG_ADD_NEW_DEVICE: {
                        DeviceBean bean = (DeviceBean) message.obj;
                        Dbug.e(tag, "MSG_ADD_NEW_DEVICE=" + bean);
                        if (bean != null) {
                            String wifiSSID = bean.getWifiSSID();
                            if (mAdapter != null && !mStationList.contains(wifiSSID)) {
                                mStationList.add(wifiSSID);
                                mAdapter.add(bean);
                                mAdapter.notifyDataSetChanged();
                            }
                        }
                        break;
                    }
                }
            }
            return false;
        }
    });

    public StaDeviceListFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.sta_device_list_fragment, container, false);
        ImageView mSwitchMode = (ImageView) view.findViewById(R.id.device_list_switch_search_mode);
        deviceListView = (ListView) view.findViewById(android.R.id.list);
        mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh);
        tvPullToRefresh = (TextView) view.findViewById(R.id.pull_to_refresh);
        mSwitchMode.setOnClickListener(this);
        deviceListView.setOnItemClickListener(this);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (getActivity() == null) return;

        mSwipeRefreshLayout.setColorSchemeColors(getResources().getColor(android.R.color.black),
                getResources().getColor(android.R.color.darker_gray),
                getResources().getColor(android.R.color.black),
                getResources().getColor(android.R.color.background_light));
        mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(Color.WHITE);
        mSwipeRefreshLayout.setSize(SwipeRefreshLayout.DEFAULT);
        mSwipeRefreshLayout.setOnRefreshListener(onRefreshListener);

        if (mAdapter == null) {
            mAdapter = new DeviceListAdapter(getActivity(), R.layout.item_device_list);
        }
        deviceListView.setAdapter(mAdapter);
    }

    @Override
    public void onResume() {
        super.onResume();
        Dbug.i(tag, "onResume: current mode=" + mApplication.getSearchMode());

        if (WifiHelper.getInstance(getContext()).isWifiClosed()) {
            ToastUtil.showToastShort(getString(R.string.tip_open_wifi));
            mAdapter.clear();
            mStationList.clear();
            mAdapter.notifyDataSetChanged();
        }
        if (mStationList != null && mStationList.size() > 0) {
            if (tvPullToRefresh.getVisibility() == View.VISIBLE) {
                tvPullToRefresh.setVisibility(View.GONE);
            }
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (IConstant.isWifiP2pEnable) {
            WifiP2pHelper.getInstance(mApplication).stopDiscoverPeers(null);
        }
    }

    private void refreshList() {
        if (mSearchStaDevice != null && mSearchStaDevice.isSearching) {
            Dbug.w(TAG, "SearchStaDevice is running");
            return;
        }
        if (mSearchStaDevice != null) {
            stopStaSearchThread();
        }
        mAdapter.clear();
        mStationList.clear();
        mSearchStaDevice = new SearchStaDevice(mHandler);
        mSearchStaDevice.start();
    }

    private final SwipeRefreshLayout.OnRefreshListener onRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            if (tvPullToRefresh.getVisibility() == View.VISIBLE) {
                tvPullToRefresh.setVisibility(View.GONE);
            }
            if (!isRefreshing) {
                isRefreshing = true;
                WifiP2pHelper.getInstance(getContext()).requestPeerList();
                mHandler.sendEmptyMessage(MSG_SEARCH_DEVICE_LIST);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        isRefreshing = false;
                        //显示或隐藏刷新进度条
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                }, 1000);
            }
        }
    };

    private void stopStaSearchThread() {
        if (mSearchStaDevice != null) {
            mSearchStaDevice.stopSearch();
            mSearchStaDevice = null;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
    }

    @Override
    public void onClick(View view) {
        if (view != null && getActivity() != null) {
            switch (view.getId()) {
                case R.id.device_list_switch_search_mode:
                    if (getActivity() != null) {
                        getActivity().getSupportFragmentManager().popBackStack();
                    }
                    break;
            }
        }
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
        if (getActivity() != null && mAdapter != null) {
            final DeviceBean deviceBean = mAdapter.getItem(position);
            if (deviceBean != null) {
                Dbug.i(tag, "isConnected="+ClientManager.getClient().isConnected() + ", wifiIP="+deviceBean.getWifiIP());
                stopStaSearchThread();
                String ip = deviceBean.getWifiIP();
                if (!TextUtils.isEmpty(ip) && !ip.equals(ClientManager.getClient().getAddress())) {
                    if (ClientManager.getClient().isConnected()) {
                        ClientManager.getClient().close();
                    }
                    ((MainActivity) getActivity()).connectDevice(ip);
                } else {
                    enterLiveVideo();
                }
                mApplication.setSearchMode(STA_SEARCH_MODE);
            } else Dbug.w(tag, "Device bean is null");
        } else Dbug.w(tag, "mAdapter is null");
    }

    private void enterLiveVideo() {
        Dbug.w(tag, "It has connected.");
        BaseFragment fragment = (BaseFragment) getActivity().getSupportFragmentManager().findFragmentByTag(VideoFragment.class.getSimpleName());
        if (fragment == null) fragment = new VideoFragment();

        ((MainActivity) getActivity()).changeFragment(R.id.container, fragment, fragment.getClass().getSimpleName());
    }

    @Override
    public void onDestroyView() {
        stopStaSearchThread();
        dismissSelectWifiDialog();
        super.onDestroyView();
    }

    private static class DeviceListAdapter extends ArrayAdapter<DeviceBean> {
        private int resourceId;
        private WeakReference<Context> mContextWeakRef;
        private WifiHelper mWifiHelper;

        DeviceListAdapter(@NonNull Context context, @LayoutRes int resource) {
            super(context, resource);
            this.resourceId = resource;
            mContextWeakRef = new WeakReference<>(context);
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null) {
                convertView = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
                viewHolder = new ViewHolder(convertView);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            DeviceBean bean = getItem(position);
            if (bean != null) {
                String deviceName = bean.getWifiSSID();
                if (!TextUtils.isEmpty(deviceName)) {
                    viewHolder.devNameTv.setText(deviceName);
                } else {
                    if (mContextWeakRef != null && mContextWeakRef.get() != null) {
                        viewHolder.devNameTv.setText(mContextWeakRef.get().getString(R.string.unknown_device_name));
                    }
                }
                if (checkDeviceConnected(bean.getMode(), bean.getWifiSSID())) {
                    viewHolder.devStateIcon.setImageResource(R.mipmap.ic_device_selected);
                } else {
                    viewHolder.devStateIcon.setImageResource(R.mipmap.ic_device_unselected);
                }
            }
            return convertView;
        }

        private class ViewHolder {
            private ImageView devStateIcon;
            private TextView devNameTv;

            ViewHolder(View view) {
                devStateIcon = (ImageView) view.findViewById(R.id.device_state_icon);
                devNameTv = (TextView) view.findViewById(R.id.device_name_text);

                view.setTag(this);
            }
        }

        private boolean checkDeviceConnected(int mode, String ssid) {
            boolean result = false;
            if (mode == DEV_STA_MODE) {
                if (ClientManager.getClient().isConnected() && ssid.equals(ClientManager.getClient().getConnectedIP())) {
                    result = true;
                }
            } else {
                if (!TextUtils.isEmpty(ssid)) {
                    if (mWifiHelper == null) {
                        mWifiHelper = WifiHelper.getInstance(MainApplication.getApplication());
                    }
                    String saveSSID = null;
                    WifiP2pDevice wifiP2pDevice = WifiP2pHelper.getInstance(getContext()).getConnectWifiDevice();
                    if (wifiP2pDevice != null) {
                        saveSSID = wifiP2pDevice.deviceName;
                    }
                    if (TextUtils.isEmpty(saveSSID)) {
                        WifiInfo wifiInfo = mWifiHelper.getWifiConnectionInfo();
                        if (wifiInfo != null) {
                            saveSSID = WifiHelper.formatSSID(wifiInfo.getSSID());
                        }
                    }
                    if (ssid.equals(saveSSID) && ClientManager.getClient().isConnected()) {
                        result = true;
                    }
                }
            }
            return result;
        }
    }

    private static class SearchStaDevice extends Thread {

        private Discovery mDiscovery;
        private WeakReference<Handler> weakReference;
        private boolean isSearching;
        private int timeCount = 0;

        SearchStaDevice(Handler mHandler) {
            mDiscovery = Discovery.newInstance();
            mDiscovery.registerOnDiscoveryListener(mOnDiscoveryListener);
            weakReference = new WeakReference<>(mHandler);
        }

        private void stopSearch() {
            isSearching = false;
            if (mDiscovery != null) {
                mDiscovery.unregisterOnDiscoveryListener(mOnDiscoveryListener);
                mDiscovery.release();
                mDiscovery = null;
            }
        }

        @Override
        public synchronized void start() {
            super.start();
            isSearching = true;
        }

        @Override
        public void run() {
            super.run();
            Dbug.i(tag, "SearchStaDevice thread start running...");
            while (isSearching) {
                if (mDiscovery != null) {
                    mDiscovery.setFilter(true);
                    mDiscovery.doDiscovery();
                    int count = 0;
                    while (count < 10 && isSearching) {
                        SystemClock.sleep(300);
                        count++;
                    }
                    if (!isSearching) break;
                    timeCount += 3;
                    if (timeCount >= 30) {
                        break;
                    }
                }
            }
            Dbug.i(tag, "SearchStaDevice thread stop running..." + isSearching);
            isSearching = false;
            timeCount = 0;
        }

        private Discovery.OnDiscoveryListener mOnDiscoveryListener = new Discovery.OnDiscoveryListener() {
            @Override
            public void onDiscovery(String remoteAddress, String msg) {
                if (!TextUtils.isEmpty(remoteAddress)) {
//                    DeviceDesc deviceDesc = AppUtils.parseDeviceDescTxt(msg);
                    DeviceBean bean = new DeviceBean();
                    bean.setWifiIP(remoteAddress);
                    bean.setMode(DEV_STA_MODE);
                    bean.setWifiSSID(remoteAddress);
                    Handler handler = weakReference.get();
                    if (handler != null) {
                        handler.sendMessage(handler.obtainMessage(MSG_ADD_NEW_DEVICE, bean));
                    }
                }
            }

            @Override
            public void onError(int errCode, String errMsg) {
                Dbug.e(tag, "code : " + errCode + " , msg : " + errMsg);
                isSearching = false;
            }
        };
    }

    private void dismissSelectWifiDialog() {
        if (mSelectWifiDialog != null) {
            if (mSelectWifiDialog.isShowing() && !isDetached()) {
                mSelectWifiDialog.dismiss();
            }
            mSelectWifiDialog = null;
        }
    }
}
